package com.yeyks.commonReference.service.config.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yeyks.common.base.Arguments;
import com.yeyks.common.constants.ConfigKey;
import com.yeyks.common.dto.DoubleDanConfig;
import com.yeyks.common.dto.NewZeroParentRate;
import com.yeyks.common.dto.ZeroParentRate;
import com.yeyks.common.dto.card.MemberCardRate;
import com.yeyks.common.dto.mq.GrabTheOrderSuccessWebsocketMessage;
import com.yeyks.common.exception.ServiceException;
import com.yeyks.common.utils.ArgumentsCheckUtil;
import com.yeyks.common.utils.DateUtils;
import com.yeyks.common.utils.Splitters;
import com.yeyks.common.utils.arithmetic.Probability;
import com.yeyks.commonReference.service.config.ConfigService;
import com.yeyks.config.dal.dao.ConfigMapper;
import com.yeyks.config.dal.domain.Config;
import com.yeyks.consumer.dal.domain.UserInfo;
import com.yeyks.consumer.service.UserInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;


/**
 * <p>
 * 动态配置数据表 服务实现类
 * </p>
 *
 * @author yun
 * @since 2019-06-25
 */
@Service
@Slf4j
public class ConfigServiceImpl extends ServiceImpl<ConfigMapper, Config> implements ConfigService {

    @Autowired
    private UserInfoService userInfoService;

    /**
     * 通过用户查询用户手机号是否在白名单中
     *
     * @param userId
     * @return
     */
    @Override
    public boolean checkWhiteList(Integer userId) {
        UserInfo userInfo = userInfoService.getById(userId);
        if (userInfo == null) {
            return false;
        }
        return checkWhiteList(userInfo.getPhone());
    }

    @Override
    public String getValue(String key) {
        Config config = baseMapper.selectValueByKey(key);
        if (config == null) {
            log.info("通过key获取不到配置项信息key = {}", key);
            throw new ServiceException("该配置项不存在");
        }
        return config.getValue();
    }

    @Override
    public Object getValueWithDefault(String key,Object defaultValue){
        Config config = baseMapper.selectValueByKey(key);
        if (config == null) {
            log.info("通过key获取不到配置项信息key = {}", key);
            return defaultValue;
        }
        return config.getValue();
    }

    /**
     * 获取C2B的搜索条件
     *
     * @return
     */
    @Override
    public Map<String, Object> getC2BConditionMap() {
        Map<String, Object> map = Maps.newHashMap();
        try {
            String value = getValue(ConfigKey.SEARCH_CONDITION);
            JSONObject jsonObject = JSONObject.parseObject(value);
            map.put("distance", jsonObject.get("distance"));
            map.put("range", jsonObject.get("range"));
            map.put("minCount", jsonObject.get("minCount"));
            map.put("maxCount", jsonObject.get("maxCount"));
            map.put("limit", jsonObject.get("limit"));
            map.put("title", jsonObject.get("title"));
            map.put("noMessage", jsonObject.get("noMessage"));
            map.put("message", jsonObject.get("message"));
        } catch (Exception e) {
            e.printStackTrace();
            map.put("distance", 20000);
            map.put("range", 75);
            map.put("minCount", 5);
            map.put("maxCount", 15);
            map.put("limit", 100);
            map.put("title", "搜索结果");
            map.put("noMessage", "该地区酒店较少");
            map.put("message", "该地区酒店较少，请调整价格重新抢单");
        }
        return map;
    }

    /**
     * 获取VIP的搜索条件
     *
     * @return
     */
    @Override
    public Map<String, Object> getVipConditionMap() {
        Map<String, Object> map = Maps.newHashMap();
        try {
            String value = getValue(ConfigKey.VIP_SEARCH_CONDITION);
            JSONObject jsonObject = JSONObject.parseObject(value);
            map.put("maxDistance", jsonObject.get("distance"));
            map.put("noMessage", jsonObject.get("noMessage"));
        } catch (Exception e) {
            e.printStackTrace();
            map.put("maxDistance", 20000);
            map.put("noMessage", "该地区酒店较少");
        }
        return map;
    }

    /**
     * 获取推广佣金比率
     *
     * @return
     */
    @Override
    public List<Probability> getProbability() {
        try {
            String value = getValue(ConfigKey.COUPON_RATE);
            if (ArgumentsCheckUtil.strIsNull(value)) {
                return defaultProbability();
            }
            return JSONObject.parseArray(value, Probability.class);
        } catch (Exception e) {
            e.printStackTrace();
            return defaultProbability();
        }
    }

    /**
     * 获取卡号规则
     *
     * @param cardType 1vip，2精选
     * @return
     */
    @Override
    public String getCardRule(Integer cardType) {
        if (1 == cardType) {
            try {
                String value = getValue(ConfigKey.CARD_NO_RULE);
                if (ArgumentsCheckUtil.strIsNull(value)) {
                    return defaultCardNoRule();
                }
                JSONObject jsonObject = JSONObject.parseObject(value);
                String head = (String) jsonObject.get("head");
                String batch = (String) jsonObject.get("batch");
                return head + batch;
            } catch (Exception e) {
                e.printStackTrace();
                return defaultCardNoRule();
            }
        }
        return getMiniCardRule();
    }

    /**
     * 获取小卡号规则
     *
     * @return
     */
    private String getMiniCardRule() {
        try {
            String value = getValue(ConfigKey.MINI_CARD_NO_RULE);
            if (ArgumentsCheckUtil.strIsNull(value)) {
                return miniDefaultCardNoRule();
            }
            JSONObject jsonObject = JSONObject.parseObject(value);
            String head = (String) jsonObject.get("head");
            String batch = (String) jsonObject.get("batch");
            return head + batch;
        } catch (Exception e) {
            e.printStackTrace();
            return miniDefaultCardNoRule();
        }
    }

    /**
     * 查询手机是否在白名单中
     *
     * @param phone
     * @return
     */
    @Override
    public boolean checkWhiteList(String phone) {
        try {
            String value = getValue(ConfigKey.PHONE_WHITE_LIST);
            if (ArgumentsCheckUtil.strIsNull(value)) {
                return false;
            }
            List<String> phoneLists = Splitters.splitToString(value, Splitters.COMMA);
            for (String phoneList : phoneLists) {
                if (phoneList != null && phoneList.equals(phone)) {
                    return true;
                }
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean checkDateIsHoliday(String date,String holidays) {
        try {
          //  String value = getValue(ConfigKey.ROOM_HOLIDAY_LIST);
            if (ArgumentsCheckUtil.strIsNull(holidays)) {
                return false;
            }
            List<String> holidayList = Splitters.splitToString(holidays, Splitters.COMMA);
            for (String holiday : holidayList) {
                if (holiday != null && holiday.equals(date)) {
                    return true;
                }
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 通过用户查询用户手机号是否在白名单中（true代表在，false代表不在）
     * 一共5个
     * key为30000，value为1
     * key为20000，value为1
     * key为10000，value为6
     * key为5000，value为6
     * key为total，value为券的总个数
     *
     * @return
     */
    @Override
    public Map<String, Integer> getGiftCouponAmount() {
        try {
            String value = getValue(ConfigKey.GIFT_COUPON_AMOUNT);
            if (ArgumentsCheckUtil.strIsNull(value)) {
                return ImmutableMap.of("30000", 0, "20000", 0, "10000", 0, "5000", 2, "total", 2);
            }
            return giftCouponAmount(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ImmutableMap.of("30000", 0, "20000", 0, "10000", 0, "5000", 2, "total", 2);
    }

    /**
     * 获取计算酒店账户余额的开始时间
     *
     * @return
     */
    @Override
    public Date getHotelDate() {
        try {
            String value = getValue(ConfigKey.HOTEL_AMOUNT_BEGIN_TIME);
            if (ArgumentsCheckUtil.strIsNull(value)) {
                return DateUtils.ymdhmsToDate("2019-07-18 12:00:00");
            }
            return DateUtils.ymdhmsToDate(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return DateUtils.ymdhmsToDate("2019-07-18 12:00:00");
    }

    /**
     * 酒店抢单提示消息
     */
    @Override
    public GrabTheOrderSuccessWebsocketMessage getHotelRobOrderMsg() {
        try {
            String value = getValue(ConfigKey.HOTEL_ROB_ORDER_MSG);
            if (Arguments.strIsNull(value)) {
                return new GrabTheOrderSuccessWebsocketMessage("恭喜您，用户【${phone}】出价${price}元已选择入住您的酒店！", "抱歉，【${phone}】出价${price}元，该订单已被其他酒店抢走，请再接再厉！");
            }
            GrabTheOrderSuccessWebsocketMessage message = JSONUtil.toBean(value, GrabTheOrderSuccessWebsocketMessage.class);
            if (null == message) {
                return new GrabTheOrderSuccessWebsocketMessage("恭喜您，用户【${phone}】出价${price}元已选择入住您的酒店！", "抱歉，【${phone}】出价${price}元，该订单已被其他酒店抢走，请再接再厉！");
            }
            return message;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new GrabTheOrderSuccessWebsocketMessage("恭喜你抢单成功", "抢单失败");
    }

    /**
     * c2b自动抢单个数
     *
     * @return
     */
    @Override
    public Integer c2bAutoRobAmount() {
        try {
            String value = getValue(ConfigKey.C2B_AUTO_ROB_AMOUNT);
            if (Arguments.strIsNull(value)) {
                return 5;
            }
            return Integer.valueOf(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 5;
    }

    /**
     * c2b搜索个数
     *
     * @return
     */
    @Override
    public Integer c2bSearchAmount() {
        try {
            String value = getValue(ConfigKey.C2B_SEARCH_AMOUNT);
            if (Arguments.strIsNull(value)) {
                return 20;
            }
            return Integer.valueOf(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 20;
    }

    /**
     * 获取抢单超时的时间的时间(毫秒)
     *
     * @return
     */
    @Override
    public Integer getRobOverTime() {
        try {
            String value = getValue(ConfigKey.C2B_ROB_OVERTIME);
            if (Arguments.strIsNull(value)) {
                return 15 * 1000;
            }
            return Integer.valueOf(value) * 1000;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 15 * 1000;
    }

    /**
     * 获取小vip佣金比率
     *
     * @return
     */
    @Override
    public MemberCardRate getMiniRate() {
        try {
            String value = getValue(ConfigKey.MINI_RATE);
            if (null == value) {
                return new MemberCardRate(2000, 2000);
            }
            return JSONUtil.toBean(value, MemberCardRate.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new MemberCardRate(2000, 2000);
    }

    /**
     * 获取0元推广的佣金比率
     *
     * @return
     */
    @Override
    public ZeroParentRate getZeroRate() {
        try {
            String value = getValue(ConfigKey.ZERO_PARENT_RATE);
            if (null == value) {
                return new ZeroParentRate(25, 50);
            }
            return JSONUtil.toBean(value, ZeroParentRate.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ZeroParentRate(25, 50);
    }

    /**
     * 获取0元推广的佣金（单位分）
     *
     * @return
     */
    @Override
    public NewZeroParentRate getNewZeroParentRate() {
        try {
            String value = getValue(ConfigKey.NEW_ZERO_PARENT_RATE);
            if (null == value) {
                return new NewZeroParentRate(400, 500);
            }
            return JSONUtil.toBean(value, NewZeroParentRate.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new NewZeroParentRate(400, 500);
    }

    private Map<String, Integer> giftCouponAmount(String value) {
        Integer total = 0;
        Map<String, Integer> resultMap = Maps.newHashMap();
        JSONObject jsonObject = JSONObject.parseObject(value);
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            resultMap.put(entry.getKey(), (Integer) entry.getValue());
            total += (Integer) entry.getValue();
        }
        resultMap.put("total", total);
        return resultMap;
    }

    private String defaultCardNoRule() {
        return "010001";
    }

    private String miniDefaultCardNoRule() {
        return "020001";
    }

    private List<Probability> defaultProbability() {
        List<Probability> probabilities = Lists.newArrayList();
        probabilities.add(new Probability(30, 50, 980));
        probabilities.add(new Probability(60, 100, 15));
        probabilities.add(new Probability(110, 190, 4));
        probabilities.add(new Probability(200, 200, 1));
        return probabilities;
    }

    /**
     * 学生推广佣金名单
     *
     * @return
     */
    @Override
    public List<String> getNewZeroUserTypeStudent() {
        try {
            String value = getValue(ConfigKey.NEW_ZERO_USER_TYPE_STUDENT);
            if (StrUtil.isBlank(value)) {
                return Lists.newArrayList();
            }
            return Arrays.asList(value.split(","));
        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    /**
     * 双旦活动时间
     *
     * @return
     */
    @Override
    public DoubleDanConfig getDoubleDanConfig() {
        try {
            String value = getValue(ConfigKey.DOUBLE_DAN);
            if (null == value) {
                return new DoubleDanConfig(new Date(1577116800000L), new Date(1546703999000L));
            }
            Map<String, Object> map = JSONUtil.parseObj(value);
            String start = (String) map.get("start");
            String end = (String) map.get("end");
            return new DoubleDanConfig(DatePattern.NORM_DATETIME_FORMAT.parse(start), DatePattern.NORM_DATETIME_FORMAT.parse(end));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new DoubleDanConfig(new Date(1577116800000L), new Date(1546703999000L));
    }
}
